import { TableInfo } from "@/entities/tableInfo.entity";
import createFile from "./createFile";

/**
 * 创建服务文件
 * @param name 
 * @param data 
 */
const createServicesFile = async (data: TableInfo) => {
    const { fieldInfoList = [], indexInfoList = [] } = data;



    //表名下划线转小驼峰
    const smallName = data.name.replace(/_(.)/g, (a: string, b: string) => `${b.toLocaleUpperCase()}`);

    //表名下划线转大驼峰
    const bigName = data.name.replace(/(?:^|_)(\w)/g, (_, c) => c.toUpperCase());

    let uniqueList: string[] = [];
    indexInfoList.forEach(item => {
        if (item.indexType == "UNIQUE") {
            uniqueList.push(item.smallHumpCode!);
        }
    })
    let findExcludeIdStr = uniqueList.map(item => {
        if (item.indexOf(",") == -1) {//单列唯一
            return `${smallName}.${item}= :${item} `
        } else { //多列唯一
            let s = item.split(',').map(j => {
                return `${smallName}.${j}= :${j} `
            }).join("AND ")
            return `(${s})`
        }
    }).join('OR ')

    const str = `
import { 
Create${bigName}Dto, 
Update${bigName}Dto, 
Query${bigName}Dto, 
Delete${bigName}Dto, 
SelectOne${bigName}Dto ,
//Sort${bigName}Dto
} from '@/dto/${smallName}.dto';
import { AppDataSource } from '@/config/AppDataSource';
import { ${bigName} } from '@/entities/${smallName}.entity';
import { In } from 'typeorm';


class ${bigName}Service {
    manager = AppDataSource.manager
    private repositor = AppDataSource.getRepository(${bigName});
    ${uniqueList.length > 0 ?
            `/**
     * 检验是否已存在唯一
     * @param data  
     * @returns 
     */ 
    async findExcludeId(data: Update${bigName}Dto) {
        const res = await this.repositor
            .createQueryBuilder('${smallName}')
            .where('${smallName}.id != :id', { id: data.id ||-1 })
            .andWhere('(${findExcludeIdStr})', data)
            .getOne();
        return res
    }`
            : ""
        }

    /**
     * 创建
     * @param data  
     * @returns 
     */    
    async add(data: Create${bigName}Dto) {        
        ${uniqueList.length > 0 ?
            `// 检查是否已存在
        const findOneName = await this.findExcludeId(data)
        if (findOneName) {
            throw new Error('存在重复');
        }`
            : ""
        }
        // 创建
        const ${smallName} = new ${bigName}();
        ${fieldInfoList.map(item => {
            if (["status", 'id', 'createdAt', 'updatedAt'].indexOf(item.smallHumpCode!) > -1) {
                return ''
            }
            return `${smallName}.${item.smallHumpCode}=data.${item.smallHumpCode};
        `
        }).join("")}           
        const result = await this.repositor.save(${smallName})
        return result;
    }
    async update(data: Update${bigName}Dto) {
            // 1. 检查是否存在
        const findOne = await this.repositor.findOneBy({
            id:data.id
        })
        if (!findOne) {
            throw new Error("数据不存在")
        }
        ${uniqueList.length > 0 ?
            `
        // 检查是否已存在
        const findOneName = await this.findExcludeId(data)
        if (findOneName) {
            throw new Error('存在重复'); 
        }`
            : ""
        }
        const ${smallName} = new ${bigName}();
        ${fieldInfoList.map(item => {
            if (['createdAt', 'updatedAt'].indexOf(item.smallHumpCode!) > -1) {
                return ''
            }
            return `${smallName}.${item.smallHumpCode}=data.${item.smallHumpCode}!;
        `
        }).join("")}
        return this.repositor.save(${smallName});
    }

    async selectOne(reqData: SelectOne${bigName}Dto) {
        const item = await this.repositor.findOneBy({
            id:reqData.id
        })
        return item;
    }

    async selectList(reqData: Query${bigName}Dto) {
        const { 
            page, 
            pageSize, 
            orderBy,
            fromDate, 
            toDate,
            ${fieldInfoList.map(item => {
            if (item.isQuery) {
                return `
            ${item.smallHumpCode},`
            } else {
                return ''
            }
        }).join('')
        }
        } = reqData;

        const queryBuilder = this.repositor
            .createQueryBuilder('${smallName}')
            .select([
                ${fieldInfoList.map(item => {
            if (item.isList) {
                return `
                '${smallName}.${item.smallHumpCode}',`
            } else {
                return ''
            }

        }).join("")}    
            ]);

        ${fieldInfoList.map(item => {
            if (item.isQuery) {
                if (item.queryType == "LIKE") {
                    return `
        if (${item.smallHumpCode}) {
            queryBuilder.andWhere('${smallName}.${item.smallHumpCode} LIKE :${item.smallHumpCode}', { name: \`%\${${item.smallHumpCode}}%\` });
        }                  
                    `
                } else if (item.queryType == "=") {
                    return `
        if (${item.smallHumpCode}) {
            queryBuilder.andWhere('${smallName}.${item.smallHumpCode} = :${item.smallHumpCode}', { ${item.smallHumpCode} });
        }
                    `
                }
            } else {
                return ''
            }

        }).join("")}
        // 添加创建日期范围查询
        if (fromDate && toDate) {
            queryBuilder.andWhere('${smallName}.createdAt BETWEEN :fromDate AND :toDate', {
                fromDate: new Date(fromDate),
                toDate: new Date(\`\${toDate}T23:59:59.999Z\`)

            });
        } else if (fromDate) {
            queryBuilder.andWhere('${smallName}.createdAt >= :fromDate', {
                fromDate: new Date(fromDate)
            });
        } else if (toDate) {
            queryBuilder.andWhere('${smallName}.createdAt <= :toDate', {
                toDate: new Date(\`\${toDate}T23:59:59.999Z\`)

            });
        }
        const [sortBy, sortOrder] = orderBy.split(" ")
        const [${smallName}, total] = await queryBuilder
            .orderBy(\`${smallName}.\${sortBy}\`, sortOrder.toLocaleUpperCase() as "ASC" | "DESC")
            .skip((page - 1) * pageSize)
            .take(pageSize)
            .getManyAndCount();
        return {
            list: ${smallName},
            total,
            page,
            pageSize,
            totalPages: Math.ceil(total / pageSize),
        };


    }
    async delete(reqData: Delete${bigName}Dto) {
        const result = await this.repositor.delete({
            id: In(reqData.ids)
        });
        return !!result.affected;

    }
    /**
    async sort(reqData: Sort${bigName}Dto) {
        const queryRunner = AppDataSource.createQueryRunner();
        await queryRunner.connect();
        await queryRunner.startTransaction();
        try {
            for (const item of reqData.list) {
                await queryRunner.manager.update(
                ${bigName},
                item.id,
                { sortOrder: item.sortOrder }
                );
            }
            await queryRunner.commitTransaction();
            return { success: true };
        } catch (err) {
            await queryRunner.rollbackTransaction();
        throw err;
        } finally {
            await queryRunner.release();
        } 
    }
    */

}

export default new ${bigName}Service();    
        
        `
    createFile(str, `services/${smallName}.service.ts`)

    return str

}
export default createServicesFile;